既存の Route 53 ホストゾーンのドメイン名を使って ALB にアクセスする構成を AWS CDK で構築してみた
こんにちは、製造ビジネステクノロジー部の若槻です。
前回のエントリでは、カスタムドメインで接続可能な ALB を AWS CDK で構築する際に、ALB に紐付ける「ACM 証明の作成まで」はダッシュボードで手動で実施しました。
今回は、Route 53 ホストゾーンのドメイン名は前回同様に既存のものを使いつつ、ALB にアクセスする構成を「証明書の作成も含めて」AWS CDK で構築してみました。
やってみた
既存の Route 53 ホストゾーン
ドメインは、AWS 上にすでに作成されている Route 53 ホストゾーンを使用します。
CDK コード
今回の構成の CDK コードは以下の通りです。
import {
aws_certificatemanager as acm,
aws_route53 as route53,
aws_ec2 as ec2,
aws_elasticloadbalancingv2 as elbv2,
aws_route53_targets as route53Targets,
Stack,
StackProps,
} from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class CdkSampleStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps) {
super(scope, id, props);
/**
* 環境変数からドメイン名を取得
*/
const domainName = process.env.DOMAIN_NAME || 'example.com';
/**
* 既存のホストゾーンを取得
*/
const hostedZone = route53.HostedZone.fromLookup(this, 'HostedZone', {
domainName,
});
/**
* ACM 証明書を作成
*/
const certificate = new acm.Certificate(this, 'Certificate', {
domainName,
validation: acm.CertificateValidation.fromDns(hostedZone),
});
/**
* VPC を作成
*/
const vpc = new ec2.Vpc(this, 'Vpc');
/**
* ALB を作成
*/
const loadBalancer = new elbv2.ApplicationLoadBalancer(
this,
'LoadBalancer',
{
vpc,
internetFacing: true,
}
);
/**
* 証明書を紐付けたリスナーを作成
*/
loadBalancer.addListener('Listener', {
port: 443,
certificates: [certificate],
defaultAction: elbv2.ListenerAction.fixedResponse(200, {
contentType: 'text/plain',
messageBody: 'Hello, CDK!',
}),
});
/**
* ホストゾーンに ALB の DNS 名をエイリアス登録
*/
new route53.ARecord(this, 'AliasRecord', {
zone: hostedZone,
target: route53.RecordTarget.fromAlias(
new route53Targets.LoadBalancerTarget(loadBalancer)
),
});
}
}
HostedZone.fromLookup で既存のホストゾーンを取得したら、下記の実装はすべて CDK で構築します。
- 証明書の作成、バリデーション
- VPC の作成
- ALB の作成
- リスナーの作成
- ホストゾーンに ALB の DNS 名をエイリアス登録
上記を CDK Deploy コマンドでデプロイします。
デプロイ後の確認
以下は CloudFormation ダッシュボードからスタックの Construct ツリーを確認した様子です。デプロイが成功していることが確認できます。
また作成された証明書を確認すると、紐付けられたドメインのステータスも Success になっておりバリデーションが成功していることが確認できます。
ホストゾーンのレコード一覧を確認すると、証明書バリデーション用の CNAME レコードと、ロードバランサーの DNS 名の Alias レコードが登録されていることが確認できます。
ここで、cdk.context.json
に差分が発生していました。ホストゾーンのルックアップの結果がキャッシュとして保管されています。以降の CDK 合成時はこのキャッシュを使って行われるので、Git 管理の対象に追加しておきましょう。
{
"availability-zones:account=XXXXXXXXXXXX:region=ap-northeast-1": [
"ap-northeast-1a",
"ap-northeast-1c",
"ap-northeast-1d"
],
"hosted-zone:account=XXXXXXXXXXXX:domainName=ZZZZZZZZZZZZ:region=ap-northeast-1": {
"Id": "/hostedzone/YYYYYYYYYYYYYYYY",
"Name": "ZZZZZZZZZZZZ",
}
}
そしてデプロイした構成の動作確認として、ドメイン名にアクセスすると、ALB からのレスポンスが返ってくることが確認できました。
$ curl https://${DOMAIN_NAME}
Hello, CDK!
トラブルシュート
CDK スタックの合成時に次のエラーが発生しました。
$ npx cdk synth
(中略)
Error: Cannot retrieve value from context provider hosted-zone since account/region are not specified at the stack level. Configure "env" with an account and region when you define your stack.See https://docs.aws.amazon.com/cdk/latest/guide/environments.html for more details.
ホストゾーンなどのルックアップを行う場合は、下記のように StackProps で env を設定して明示的に AWS アカウントおよびリージョンを指定する必要がありました。
import { App } from 'aws-cdk-lib';
import { CdkSampleStack } from '../lib/cdk-sample-stack';
const app = new App();
new CdkSampleStack(app, 'CdkSampleStack', {
/**
* 環境変数からリージョンとアカウント ID を取得
*
* MEMO: ホストゾーンの Lookup にはリージョンおよびアカウント ID の指定が必要
*/
env: {
region: process.env.CDK_DEFAULT_REGION,
account: process.env.CDK_DEFAULT_ACCOUNT,
},
});
おわりに
既存の Route 53 ホストゾーンのドメイン名を使って ALB にアクセスする構成を AWS CDK で構築してみました。
CDK でインフラを管理している場合でも証明書の作成までは手動で行うパターンも多いと思いますが、実はホストゾーンが作成さえされていれば、今回紹介したように証明書のバリデーションまで CDK で一発で構築できます。参考にしてみてください。
以上